#include "fan_control.h"
#include "function_interface.h"
#include "types.h"
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
#include "./OverUnderX/OverTemperature.h"
#include "debug.h"
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "misc.h"


//两档转速
#if 1
/*
    任一器件高温或当前功率达到60%就满转
    设备关机后继续满转5分钟，当定时器启动时强制满转 不执行温度策略。
*/

#if 1
/* 各器件温度阈值 */
#define START_TEMP_THR_REACTOR          (70)   /* 电抗起风机门槛温度     */
#define START_TEMP_THR_BUSCAP           (55)   /* 母排电容起风机门槛温度 */
#define START_TEMP_THR_IGBT             (50)   /* 模块起风机门槛温度     */
#define START_PWR_THR_POWER             (60)   /* 当前功率起风机门槛     */

#define STOP_TEMP_THR_REACTOR           (58)   /* 电抗停风机门槛温度     */
#define STOP_TEMP_THR_BUSCAP            (43)   /* 母排电容停风机门槛温度 */
#define STOP_TEMP_THR_IGBT              (43)   /* 模块停风机门槛温度     */
#define STOP_PWR_THR_POWER              (60)   /* 当前功率停风机门槛     */

#endif

#if 1
/* 风机转速 */
#define FAN_ROTARY_SPEED_0  (0)
#define FAN_ROTARY_SPEED_100  (100)
#endif

static fanStateType fanState = {0};

int Tool_GetTheMax(int* pArray,int size/*元素个数*/)
{
    if(!pArray)
    {
        printf("%s parameter 'pArray' is NULL.\n",__FUNCTION__);
        return 0;
    }
    int max=0;
    int index=0;
    for(max=pArray[index];index<size;index++)
    {
        if(pArray[index] > max)
        {
            max=pArray[index];
        }
    }
    return max;
}


static timer_t timeId;

static void timer_handler(union sigval arg)
{
    fanStateType *pFanState = &fanState;
    pFanState->fanTimerState = FAN_TIMER_STATE_OFF;
    printf("Fan Rotary Speed 100%% 5Min timer to finish. \n");
}

void create_timer_by_thread(void)
{
    struct sigevent sigEvt;
    struct itimerspec timerVal;

    sigEvt.sigev_notify = SIGEV_THREAD;
    sigEvt.sigev_notify_function = timer_handler;
    sigEvt.sigev_value.sival_int = 0;
    sigEvt.sigev_notify_attributes = NULL;
    if(timer_create(CLOCK_MONOTONIC, &sigEvt, &timeId) == -1)
    {
        PERROR("create timer to start failed");
        return;
    }

    /*第一次调用后,每次调用间隔时间,为0表示只调用一次*/
    timerVal.it_interval.tv_sec = 0;
    timerVal.it_interval.tv_nsec = 0;
    /*第一次调用时间,即程序跑到这多久后启动定时器*/
    timerVal.it_value.tv_sec = 60*5;
    timerVal.it_value.tv_nsec = 0;

    if(timer_settime(timeId, 0, &timerVal, NULL) == -1)
    {
        PERROR("timer_settime failed");
        return;
    }
    
    printf("Fan Rotary Speed 100%% 5Min timer to start. \n");

}

/*获取风机转速*/
uint16_t FanControl_SpeedGet(void)
{
    fanStateType *pFanState = &fanState;

    return pFanState->currentState;
}

void FanControl_Thread(void *pPara)
{
    Misc_InitThread(__func__);

    int temp[TEMP_MONITOR_AREA_QTY];
    float areaTemp,devicesTemp;
    fanCtrlMonitPointType monitPoint;
    fpagDataFsm_t fpgaState;
    fpagDataFsm_t prevState;

    float ratedPower_1kw=0,actPower_1kw=0,currPower_1kw=0,currPower_Percent=0;

    static fsmStateType fsmState = {0};
    fanStateType *pFanState = &fanState;
    fanCtrlMonitPointType* pMonitPoint = &monitPoint;
    

    while(1)
    {
        //获取各器件温度
        //电抗
        FuncInf_GetIsoBoardData(FUNCINF_ISO_BOARD_DATA_TYPE_TEMP_REACT,&devicesTemp);
        pMonitPoint->monitPointMaxTemp.tempReactor_1C = (int)devicesTemp;

        //母排电容
        FuncInf_GetIsoBoardData(FUNCINF_ISO_BOARD_DATA_TYPE_TEMP_BUSCAP,&devicesTemp);
        pMonitPoint->monitPointMaxTemp.tempBuscap_1C = (int)devicesTemp;

        //IGBT
        for(int areaIndex=0;areaIndex<TEMP_MONITOR_AREA_QTY;areaIndex++)
        {
            
            FuncInf_GetIgbtTemperature(areaIndex,&areaTemp);
            temp[areaIndex] = (int16_t)areaTemp;
        }
        pMonitPoint->monitPointMaxTemp.tempIgbt_1C = Tool_GetTheMax(temp,TEMP_MONITOR_AREA_QTY);

        //当前功率百分比
        FuncInf_GetPower(FUNCINF_PWR_TYPE_ACT,&currPower_1kw);
        if(FuncInf_GetExtremeValue(FUNCINF_EXTR_VAL_TYPE_AC_P_MAX,&ratedPower_1kw) == FUNCINF_ERR_NONE)
        {
            actPower_1kw = (currPower_1kw < 0) ? (currPower_1kw*-1):currPower_1kw;
            currPower_Percent =  actPower_1kw / (ratedPower_1kw/1.3) * 100;
        }
#if 1
        printf("Fan Rotary currentSpeed:%d%%.\n",pFanState->currentState);
        switch(pFanState->currentState)
        {
            case FAN_ROTARY_SPEED_0://停转
            {
                if((pMonitPoint->monitPointMaxTemp.tempReactor_1C > START_TEMP_THR_REACTOR)
                    ||(pMonitPoint->monitPointMaxTemp.tempBuscap_1C > START_TEMP_THR_BUSCAP)
                    ||(pMonitPoint->monitPointMaxTemp.tempIgbt_1C > START_TEMP_THR_IGBT)
                    ||(currPower_Percent > START_PWR_THR_POWER)
                    )
                {
                    printf("Fan Rotary Speed to 100%%.\n");
                    pFanState->nextState = FAN_ROTARY_SPEED_100;
                }
            }break;
            case FAN_ROTARY_SPEED_100://满转
            {
                if((pMonitPoint->monitPointMaxTemp.tempReactor_1C <= STOP_TEMP_THR_REACTOR)
                    &&(pMonitPoint->monitPointMaxTemp.tempBuscap_1C <= STOP_TEMP_THR_BUSCAP)
                    &&(pMonitPoint->monitPointMaxTemp.tempIgbt_1C <= STOP_TEMP_THR_IGBT)
                    &&(currPower_Percent <= STOP_PWR_THR_POWER)
                    )
                {
                    printf("Fan Rotary Speed to 0%%.\n");
                    pFanState->nextState = FAN_ROTARY_SPEED_0;
                }
            }break;
        }

        //变更风机转速 (定时器关闭时生效)
        if((pFanState->currentState != pFanState->nextState) 
            && (pFanState->fanTimerState == FAN_TIMER_STATE_OFF))
        {
            pFanState->prevState = pFanState->currentState;
            pFanState->currentState = pFanState->nextState;

            printf("Fan Rotary Speed %d%% to %d%%.\n",pFanState->prevState,pFanState->currentState);

        }
#endif

#if 1
        //检测运行状态是否发生改变
        if((FUNCINF_ERR_NONE == FuncInf_GetFsm(FUNCINF_FSM_TYPE_1_LAST_TIME,&prevState))
            && (FUNCINF_ERR_NONE == FuncInf_GetFsm(FUNCINF_FSM_TYPE_THIS_TIME,&fpgaState)))
        {
            if(fsmState.currentState != fpgaState)
            {
                fsmState.currentState = fpgaState;
                fsmState.StateChangeFlag = FSM_STATE_CHANGE_ON;
            }
        }
        fsmState.prevState = prevState;
        //PCS运行状态发生变化
        if(fsmState.StateChangeFlag == FSM_STATE_CHANGE_ON)
        {
            //PCS从工作态切换到非工作态强制满转5分钟
            if((fsmState.prevState == FUNCINF_FSM_WORKING)
                && (fsmState.currentState != FUNCINF_FSM_WORKING))
            {
                //开启5分钟定时器
                pFanState->fanTimerState = FAN_TIMER_STATE_ON;
                pFanState->nextState = FAN_ROTARY_SPEED_100;
                pFanState->prevState = pFanState->currentState;
                pFanState->currentState = pFanState->nextState;
                //删掉当前定时器
                timer_delete(timeId);
                create_timer_by_thread();

                fsmState.StateChangeFlag = FSM_STATE_CHANGE_OFF;

                printf("pcsState Working to Not Working ,Fan Rotary Speed Force to 100%% 5Min.\n");

            }
        }
#endif
        sleep(1);
    }
}
#endif

//三档转速
#if 0
/*
    任一器件到中温门坎 80%启动风机，任一器件到高温门坎 100%启动风机。
    所有器件温度退出中温门槛 停风机，所有器件温度退出高温门槛 风机100%转速降为80%转速。
    设备关机后继续满转5分钟，当定时器启动时强制满转 不执行温度策略。
*/

#if 1
/* 各器件温度阈值 */
#define STOP_TEMP_THR_REACTOR         (58)   /* 电抗退出中温门槛温度     */
#define STOP_TEMP_THR_BUSCAP          (43)   /* 母排电容退出中温门槛温度 */
#define STOP_TEMP_THR_FILTERCAP       (38)   /* 滤波电容退出中温门槛温度 */
#define STOP_TEMP_THR_IGBT            (48)   /* 模块退出中温门槛温度     */
#define STOP_TEMP_THR_AC_CABINET      (23)   /* 交流柜退出中温门槛温度   */

#define LOW_TEMP_THR_REACTOR          (60)   /* 电抗中温门槛温度     */
#define LOW_TEMP_THR_BUSCAP           (45)   /* 母排电容中温门槛温度 */
#define LOW_TEMP_THR_FILTERCAP        (40)   /* 滤波电容中温门槛温度 */
#define LOW_TEMP_THR_IGBT             (50)   /* 模块中温门槛温度     */
#define LOW_TEMP_THR_AC_CABINET       (25)   /* 交流柜中温门槛温度   */

#define MID_TEMP_THR_REACTOR          (65)   /* 电抗退出高温门槛温度     */
#define MID_TEMP_THR_BUSCAP           (50)   /* 母排电容退出高温门槛温度 */
#define MID_TEMP_THR_FILTERCAP        (45)   /* 滤波电容退出高温门槛温度 */
#define MID_TEMP_THR_IGBT             (55)   /* 模块退出高温门槛温度     */
#define MID_TEMP_THR_AC_CABINET       (30)   /* 交流柜退出高温门槛温度   */

#define HIGH_TEMP_THR_REACTOR         (70)   /* 电抗高温门槛温度     */
#define HIGH_TEMP_THR_BUSCAP          (55)   /* 母排电容高温门槛温度 */
#define HIGH_TEMP_THR_FILTERCAP       (50)   /* 滤波电容高温门槛温度 */
#define HIGH_TEMP_THR_IGBT            (60)   /* 模块高温门槛温度     */
#define HIGH_TEMP_THR_AC_CABINET      (35)   /* 交流柜高温门槛温度   */
#endif

#if 1
/* 风机转速 */
#define FAN_ROTARY_SPEED_0  (0)
#define FAN_ROTARY_SPEED_80   (80)
#define FAN_ROTARY_SPEED_100  (100)
#endif

static fanStateType fanState = {0};

int Tool_GetTheMax(int* pArray,int size/*元素个数*/)
{
    if(!pArray)
    {
        printf("%s parameter 'pArray' is NULL.\n",__FUNCTION__);
        return 0;
    }
    int max=0;
    int index=0;
    for(max=pArray[index];index<size;index++)
    {
        if(pArray[index] > max)
        {
            max=pArray[index];
        }
    }
    return max;
}


static timer_t timeId;

static void timer_handler(union sigval arg)
{
    fanStateType *pFanState = &fanState;
    pFanState->fanTimerState = FAN_TIMER_STATE_OFF;
    printf("Fan Rotary Speed 100%% 5Min timer to finish. \n");
}

void create_timer_by_thread(void)
{
    struct sigevent sigEvt;
    struct itimerspec timerVal;

    sigEvt.sigev_notify = SIGEV_THREAD;
    sigEvt.sigev_notify_function = timer_handler;
    sigEvt.sigev_value.sival_int = 0;
    sigEvt.sigev_notify_attributes = NULL;
    if(timer_create(CLOCK_REALTIME, &sigEvt, &timeId) == -1)
    {
        PERROR("create timer to start failed");
        return;
    }

    /*第一次调用后,每次调用间隔时间,为0表示只调用一次*/
    timerVal.it_interval.tv_sec = 0;
    timerVal.it_interval.tv_nsec = 0;
    /*第一次调用时间,即程序跑到这多久后启动定时器*/
    timerVal.it_value.tv_sec = 60*5;
    timerVal.it_value.tv_nsec = 0;

    if(timer_settime(timeId, 0, &timerVal, NULL) == -1)
    {
        PERROR("timer_settime failed");
        return;
    }
    
    printf("Fan Rotary Speed 100%% 5Min timer to start. \n");

}

/*获取风机转速*/
uint16_t FanControl_SpeedGet(void)
{
    fanStateType *pFanState = &fanState;

    return pFanState->currentState;
}

void FanControl_Thread(void *pPara)
{
    Misc_InitThread(__func__);

    int temp[TEMP_MONITOR_AREA_QTY];
    float areaTemp,devicesTemp;
    fanCtrlMonitPointType monitPoint;
    fpagDataFsm_t fpgaState;

    fsmStateType fsmState = {0};
    fanStateType *pFanState = &fanState;
    fanCtrlMonitPointType* pMonitPoint = &monitPoint;

    while(1)
    {
        //获取各器件温度
        //电抗
        FuncInf_GetIsoBoardData(FUNCINF_ISO_BOARD_DATA_TYPE_TEMP_REACT,&devicesTemp);
        pMonitPoint->monitPointMaxTemp.tempReactor_1C = (int)devicesTemp;

        //母排电容
        FuncInf_GetIsoBoardData(FUNCINF_ISO_BOARD_DATA_TYPE_TEMP_BUSCAP,&devicesTemp);
        pMonitPoint->monitPointMaxTemp.tempBuscap_1C = (int)devicesTemp;

        //交流柜
        FuncInf_GetIsoBoardData(FUNCINF_ISO_BOARD_DATA_TYPE_TEMP_ACCBNT,&devicesTemp);
        pMonitPoint->monitPointMaxTemp.tempAcCabinet_1C = (int)devicesTemp;

        //滤波电容
        FuncInf_GetIsoBoardData(FUNCINF_ISO_BOARD_DATA_TYPE_TEMP_FLTCAP1,&devicesTemp);
        temp[0] = (int)devicesTemp;
        FuncInf_GetIsoBoardData(FUNCINF_ISO_BOARD_DATA_TYPE_TEMP_FLTCAP2,&devicesTemp);
        temp[1] = (int)devicesTemp;
        pMonitPoint->monitPointMaxTemp.tempFiltercap_1C = Tool_GetTheMax(temp,2);

        //IGBT
        for(int areaIndex=0;areaIndex<TEMP_MONITOR_AREA_QTY;areaIndex++)
        {
            
            FuncInf_GetIgbtTemperature(areaIndex,&areaTemp);
            temp[areaIndex] = (int16_t)areaTemp;
        }
        pMonitPoint->monitPointMaxTemp.tempIgbt_1C = Tool_GetTheMax(temp,TEMP_MONITOR_AREA_QTY);

#if 1
        printf("Fan Rotary currentSpeed:%d%%.\n",pFanState->currentState);
        switch(pFanState->currentState)
        {
            case FAN_ROTARY_SPEED_0://停转
            {
                if((pMonitPoint->monitPointMaxTemp.tempReactor_1C > LOW_TEMP_THR_REACTOR)
                    ||(pMonitPoint->monitPointMaxTemp.tempBuscap_1C > LOW_TEMP_THR_BUSCAP)
                    ||(pMonitPoint->monitPointMaxTemp.tempFiltercap_1C > LOW_TEMP_THR_FILTERCAP)
                    ||(pMonitPoint->monitPointMaxTemp.tempIgbt_1C > LOW_TEMP_THR_IGBT)
                    ||(pMonitPoint->monitPointMaxTemp.tempAcCabinet_1C > LOW_TEMP_THR_AC_CABINET)
                    )
                {
                    printf("Fan Rotary Speed to 80%%.\n");
                    pFanState->nextState = FAN_ROTARY_SPEED_80;
                }

            }break;
            case FAN_ROTARY_SPEED_80://80%速度转
            {
                if((pMonitPoint->monitPointMaxTemp.tempReactor_1C > HIGH_TEMP_THR_REACTOR)
                    ||(pMonitPoint->monitPointMaxTemp.tempBuscap_1C > HIGH_TEMP_THR_BUSCAP)
                    ||(pMonitPoint->monitPointMaxTemp.tempFiltercap_1C > HIGH_TEMP_THR_FILTERCAP)
                    ||(pMonitPoint->monitPointMaxTemp.tempIgbt_1C > HIGH_TEMP_THR_IGBT)
                    ||(pMonitPoint->monitPointMaxTemp.tempAcCabinet_1C > HIGH_TEMP_THR_AC_CABINET)
                    )
                {
                    printf("Fan Rotary Speed to 100%%.\n");
                    pFanState->nextState = FAN_ROTARY_SPEED_100;
                }
                if((pMonitPoint->monitPointMaxTemp.tempReactor_1C <= STOP_TEMP_THR_REACTOR)
                    &&(pMonitPoint->monitPointMaxTemp.tempBuscap_1C <= STOP_TEMP_THR_BUSCAP)
                    &&(pMonitPoint->monitPointMaxTemp.tempFiltercap_1C <= STOP_TEMP_THR_FILTERCAP)
                    &&(pMonitPoint->monitPointMaxTemp.tempIgbt_1C <= STOP_TEMP_THR_IGBT)
                    &&(pMonitPoint->monitPointMaxTemp.tempAcCabinet_1C <= STOP_TEMP_THR_AC_CABINET)
                    )
                {
                    printf("Fan Rotary Speed to 0%%.\n");
                    pFanState->nextState = FAN_ROTARY_SPEED_0;
                }
            }break;
            case FAN_ROTARY_SPEED_100://满转
            {
                if((pMonitPoint->monitPointMaxTemp.tempReactor_1C <= MID_TEMP_THR_REACTOR)
                    &&(pMonitPoint->monitPointMaxTemp.tempBuscap_1C <= MID_TEMP_THR_BUSCAP)
                    &&(pMonitPoint->monitPointMaxTemp.tempFiltercap_1C <= MID_TEMP_THR_FILTERCAP)
                    &&(pMonitPoint->monitPointMaxTemp.tempIgbt_1C <= MID_TEMP_THR_IGBT)
                    &&(pMonitPoint->monitPointMaxTemp.tempAcCabinet_1C <= MID_TEMP_THR_AC_CABINET)
                    )
                {
                    printf("Fan Rotary Speed to 80%%.\n");
                    pFanState->nextState = FAN_ROTARY_SPEED_80;
                }
            }break;
        }

        //变更风机转速 (定时器关闭时生效)
        if((pFanState->currentState != pFanState->nextState) 
            && (pFanState->fanTimerState == FAN_TIMER_STATE_OFF))
        {
            pFanState->prevState = pFanState->currentState;
            pFanState->currentState = pFanState->nextState;

            printf("Fan Rotary Speed %d%% to %d%%.\n",pFanState->prevState,pFanState->currentState);

        }
#endif

#if 1
        //检测运行状态是否发生改变
        fpagDataFsm_t prevState;
        if((FUNCINF_ERR_NONE != FuncInf_GetFsm(FUNCINF_FSM_TYPE_1_LAST_TIME,&prevState))
            && (FUNCINF_ERR_NONE != FuncInf_GetFsm(FUNCINF_FSM_TYPE_THIS_TIME,&fpgaState)))
        {
            if(fsmState.currentState != fpgaState)
            {
                fsmState.currentState = fpgaState;
                fsmState.StateChangeFlag = FSM_STATE_CHANGE_ON;
            }
        }
        fsmState.prevState = prevState;
        //PCS运行状态发生变化
        if(fsmState.StateChangeFlag == FSM_STATE_CHANGE_ON)
        {
            //PCS从工作态切换到非工作态强制满转5分钟
            if((fsmState.prevState == FUNCINF_FSM_WORKING)
                && (fsmState.currentState != FUNCINF_FSM_WORKING))
            {
                //开启5分钟定时器
                pFanState->fanTimerState = FAN_TIMER_STATE_ON;
                pFanState->nextState = FAN_ROTARY_SPEED_100;
                pFanState->prevState = pFanState->currentState;
                pFanState->currentState = pFanState->nextState;
                //删掉当前定时器
                timer_delete(timeId);
                create_timer_by_thread();

                fsmState.StateChangeFlag = FSM_STATE_CHANGE_OFF;

                printf("pcsState Working to Not Working ,Fan Rotary Speed Force to 100%% 5Min.\n");

            }
        }
#endif
        sleep(1);
    }
}
#endif



